﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using TestByWire.AttributeHandlers;
using Microsoft.Practices.Unity;

namespace TestByWire.Test
{
    [TestClass]
    public class TestTargetBuilderTest
    {
        [TestMethod]
        public void Constructor_MustThrow_WhenStackIsNull()
        {
            var exception = AssertEx.Throws<ArgumentNullException>(() => new TestTargetBuilder(null));

            Assert.AreEqual("stack", exception.ParamName);
        }

        [TestMethod]
        public void InitializeTestTarget_MustInitializePreCreationBuildPlan_WhenTestMethodAttributeIsDetected()
        {
			new TargetInvokerUnderTest(GetType());
            TestTargetBuilder testTargetBuilder = SetupGreenflow();

            testTargetBuilder.InitializeTestTarget();
                
            var buildPlan = TargetInvoker.Container.Resolve<IAttributeBuildPlan>(PipelinePosition.PreCreation.ToString());
            Assert.IsNotNull(buildPlan);
        }

        [TestMethod]
        public void InitializeTestTarget_MustInitializePostCreationBuildPlan_WhenTestMethodAttributeIsDetected()
        {
			new TargetInvokerUnderTest(GetType());
            TestTargetBuilder testTargetBuilder = SetupGreenflow();

            testTargetBuilder.InitializeTestTarget();

            var buildPlan = TargetInvoker.Container.Resolve<IAttributeBuildPlan>(PipelinePosition.PostCreation.ToString());
            Assert.IsNotNull(buildPlan);
        }

        private TestTargetBuilder SetupGreenflow()
        {
            var stack = MockRepository.GenerateStub<IStack>();
            var stackFrame = MockRepository.GenerateStub<IStackFrameInfo>();
            stackFrame.Stub(s => s.IsDefined(Arg<Type>.Is.Anything)).Return(true);
            stackFrame.Stub(s => s.Method).Return(GetType().GetMethod("InitializeTestTarget_MustInitializePreCreationBuildPlan_WhenTestMethodAttributeIsDetected"));
            var frames = new List<IStackFrameInfo> { stackFrame };
            stack.Stub(s => s.GetStackFrames()).Return(frames);
            var testTargetBuilder = new TestTargetBuilder(stack);
            TargetInvoker.Container = new UnityContainer();
            return testTargetBuilder;
        }
    }
}
